package org.dromara.bean.util.wxApi;

import com.alibaba.fastjson.JSONObject;

import jakarta.servlet.ServletInputStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dromara.bean.config.WxPaymentConfig;
import org.dromara.bean.constant.CommonConstant;
import org.dromara.bean.domain.pay.OrderModel;
import org.dromara.bean.domain.vo.Result;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.domain.model.ReturnOrderModel;



import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Administrator
 */
public class WeChatUtil {

    /**
     * 封装统一下单数据
     */
    public static Map<String, String> unifiedOrderDataMap(OrderModel orderModel, WxPaymentConfig wxConfig) throws UnknownHostException {
        Double total = orderModel.getTotalFee().doubleValue() * 100;
        Integer totalFee = total.intValue();
        Map<String, String> map = new HashMap<String, String>();

        map.put("notify_url", wxConfig.getNotifyUrl());
        map.put("body", "支付订单");
        map.put("out_trade_no", orderModel.getOrderNumber());
        map.put("total_fee", String.valueOf(totalFee));
        map.put("spbill_create_ip", InetAddress.getLocalHost().getHostAddress());

        map.put("trade_type", "JSAPI");
        map.put("openid", orderModel.getOpenId());//小程序自动获取


        return map;
    }

    /**
     * 回调返回结果
     *
     * @return
     */
    public static String resultData() {
        String resultXmlData = "<xml><return_code><![CDATA[SUCCESS]]</return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
        return resultXmlData;
    }

    /**
     * 这是微信回调结果处理
     *
     * @param instream
     * @return
     * @throws IOException
     * @throws DocumentException
     */
    public static R<?> payNotifyResult(ServletInputStream instream) throws IOException, DocumentException {
        ReturnOrderModel result = new ReturnOrderModel();
        StringBuilder sb = new StringBuilder();
        byte[] buff = new byte[1024];
        int len;
        while ((len = instream.read(buff)) != -1) {
            sb.append(new String(buff, 0, len));
        }
        String wxResponseText = sb.toString();
        if ("".equals(wxResponseText)) {
            result.setMsgCodeDes("解析返回结果失败");
            result.setReturnCode(0);
            result.setResultCode(0);
            return R.ok(result);
        }
        //开始解析xml字符串
        Document document = DocumentHelper.parseText(wxResponseText);
        Element root = document.getRootElement();
        //查询状态
        Element successEl = root.element("return_code");
        String success = successEl.getStringValue();
        Element return_msgEl;
        String return_msg = "";
        String err_code = "";
        String err_code_des = "";
        //错误码
        Element err_codeEl = root.element("err_code");
        if (err_codeEl != null) {
            err_code = err_codeEl.getStringValue();
        }

        //错误描述
        Element err_code_desEl = root.element("err_code_des");
        if (err_code_desEl != null) {
            err_code_des = err_code_desEl.getStringValue();
        }
        if (CommonConstant.WX_CODE_SUCCESS.equals(success)) {
            //逻辑调取成功
            result.setReturnCode(1);
            //查询状态
            Element resultCodeEl = root.element("result_code");
            String resultCode = resultCodeEl.getStringValue();
            if (CommonConstant.WX_CODE_SUCCESS.equals(resultCode)) {
                //业务处理成功
                result.setResultCode(1);
            }
            //商户订单号
            Element orderNoEl = root.element("out_trade_no");
            String orderNo = orderNoEl.getStringValue();

            Element timeEndEl = root.element("time_end");
            String timeEnd = timeEndEl.getStringValue();
            //以防扫码时候存订单没存上 所有多放点数据 一遍插入时候使用 正常情况肯定都是修改updateOrder 但是以防万一
            Element openidEl = root.element("openid");
            String openid = openidEl.getStringValue();
            //金额
            Element totalFeeEl = root.element("total_fee");
            String totalFeeStr = totalFeeEl.getStringValue();
            //转成int
            int totalFeeInt = Integer.parseInt(totalFeeStr);
            Double totalFee = Double.valueOf(totalFeeInt / 100);

            result.setOpenId(openid);
            result.setMsgCode(err_code);
            result.setMsgCodeDes(err_code_des);
            result.setOrderNumber(orderNo);
            result.setTotalFee(totalFee);
        } else {
            result.setReturnCode(0);
            result.setResultCode(0);
            //查询状态
            return_msgEl = root.element("return_msg");
            if (return_msgEl != null) {
                return_msg = return_msgEl.getStringValue();
                result.setMsgCode(return_msg);
            }
        }
        return R.ok(result);
    }

    /**
     * 回调返回结果
     *
     * @return
     * @throws DocumentException
     */
    public static String resultXmlData(Map<String, String> param) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        for (Map.Entry<String, String> entry : param.entrySet()) {
            sb.append("<" + entry.getKey() + ">");
            sb.append(entry.getValue());
            sb.append("</" + entry.getKey() + ">");
        }
        sb.append("</xml>");
        return sb.toString();
    }

    public static R refundNotifyResult(ServletInputStream instream) throws IOException, DocumentException {
        StringBuilder sb = new StringBuilder();
        byte[] buff = new byte[1024];
        int len;
        while ((len = instream.read(buff)) != -1) {
            sb.append(new String(buff, 0, len));
        }
        String wxResponseText = sb.toString();
        if ("".equals(wxResponseText)) {
            return R.ok("解析返回结果失败");
        }
        JSONObject responseObj = JSONObject.parseObject(wxResponseText);
        return R.ok(responseObj.getString("event_type"));
    }


}
